package visitor;

/**
 * visitor
 * 举例子
 * 装机 整机进来根据不同的人折扣不同
 * 机器的件就那几种所以比较固定
 *
 * 思考流程
 * 1、定义出所有硬件的折扣 这样可以针对不同的对象有不同折扣先定一个折扣类模版实现的不同种类折扣不同。
 * 2、定义硬件的抽象价格 这里价格是基础价格 然后不同的硬件调用对应上面类的对应方法。在把自己传进去可以拿到当前的基础价格。
 * 3、Discount 参数 ComputerPart 都有getpic可以根据不同的基础价格得出不同的折扣价格。
 * 4、创建硬件的实现
 * 5、创建computer 里面有固定的硬件
 * 6、accept 可以接待 Discount 它的实现着
 * 7、最后由Discount他的实现着去得到相应的折扣
 *
 * 注意一定是在主类固定的情况用这个设计模式 Computer 内部类固定 最主要的做编译器的地方。
 */

/**
 * 所有的件都有一个基础价格
 * 第二个价格可以根据不同的人打不同的折扣。
 */
abstract class Discount{
    abstract void visitorCpu(ComputerPart c);
    abstract void visitorMemory(ComputerPart c);
    abstract void visitorBoard(ComputerPart c);
}

/**
 * 学生半价
 */
class StudentDiscount extends Discount{
    @Override
    void visitorCpu(ComputerPart c) {
        System.out.println(c.getPic() * 0.5);
    }

    @Override
    void visitorMemory(ComputerPart c) {
        System.out.println(c.getPic() * 0.5);
    }

    @Override
    void visitorBoard(ComputerPart c) {
        System.out.println(c.getPic() * 0.5);
    }
}

/**
 * 所有硬件都有根据不同种类获取不同的折扣方法
 * 在就是基础的折扣
 */
abstract class ComputerPart{
    abstract void accept(Discount d);
    abstract double getPic();
}

class Cpu extends ComputerPart{
    void accept(Discount d){
        d.visitorCpu(this);
    }
    double getPic(){
        return 3000;
    }
}

class Memory extends ComputerPart{
    void accept(Discount d){
        d.visitorMemory(this);
    }
    double getPic(){
        return 100;
    }
}

class Borad extends ComputerPart{
    void accept(Discount d){
        d.visitorBoard(this);
    }
    double getPic(){
        return 823.12;
    }
}

/**
 * 机器
 */
class Computer{
    ComputerPart Cpu = new Cpu(); // cpu
    ComputerPart Memory = new Memory(); // memory
    ComputerPart board = new Borad(); // board

    void accept(Discount discount){
        this.Cpu.accept(discount);
        this.Memory.accept(discount);
        this.board.accept(discount);
    }
}



public class visitor {
    public static void main(String[] args){
        System.out.println("visitor ");

        Computer computer = new Computer();
        StudentDiscount studentDiscount = new StudentDiscount();

        computer.accept(studentDiscount);
    }
}
